package deanandjames.domain;

import deanandjames.configuration.Configuration;

import javax.vecmath.Point2d;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class AsteroidField {
	private static final double MINIMUM_ASTEROID_SIZE = 10.0;
	private static final int MINIMUM_SIDES_TO_AN_ASTEROID = 5;
	private static final double TWO_PI = Math.PI * 2;
	private final List<Asteroid> asteroids;
	private final int gameHeight;

	public AsteroidField(int gameWidth, int gameHeight, int numberOfAsteroids) {
		this.gameHeight = gameHeight;
		asteroids = new ArrayList<Asteroid>();

		for (int asteroidNumber = 1; asteroidNumber <= numberOfAsteroids; asteroidNumber++) {
			asteroids.add(createAsteroid(gameWidth, gameHeight, asteroidNumber));
		}
	}

	public void animate() {
		for (Asteroid asteroid : asteroids) {
			asteroid.animate();
		}
	}

	private Asteroid createAsteroid(int gameWidth, int gameHeight, int asteroidNumber) {
		double randomX = gameWidth * Math.random();
		double randomY = gameHeight * Math.random();
		int size = (int) (MINIMUM_ASTEROID_SIZE + 10.0 * Math.random() * asteroidNumber);
		int numberOfSides = (int) (MINIMUM_SIDES_TO_AN_ASTEROID + Math.random() * asteroidNumber);
		return new Asteroid(new Point2d(randomX, randomY), generateRandomHeading(), numberOfSides, size, Color.gray, gameWidth, gameHeight);
	}

	public boolean doesAnythingCollide(Boundable boundable) {
		for (Asteroid asteroid : asteroids) {
			if (asteroid.intersects(boundable)) {
				return true;
			}
		}
		return false;
	}

	public void draw(Graphics2D graphics) {
		if (Configuration.getInstance().isDebugEnabled()) {
			graphics.drawString(asteroids.size() + " asteroids.", 10, gameHeight);
		}
		int numberActive = 0;
		for (Asteroid asteroid : asteroids) {
			if (!asteroid.isDisabled()) {
				asteroid.draw(graphics);
				numberActive++;
			}
		}
		if (Configuration.getInstance().isDebugEnabled()) {
			graphics.drawString(numberActive + " active.", 10, gameHeight - 60);
		}
	}

	private List<Asteroid> findAsteroidsThatCollide(Boundable boundable) {
		List<Asteroid> asteroidsThatCollide = new ArrayList<Asteroid>();
		for (Asteroid asteroid : asteroids) {
			if (asteroid.intersects(boundable)) {
				asteroidsThatCollide.add(asteroid);
			}
		}
		return asteroidsThatCollide;
	}

	private double generateRandomHeading() {
		return TWO_PI * Math.random();
	}

	public boolean removeAsteroidsThatCollide(Boundable boundable) {
		List<Asteroid> asteroidsThatCollide = findAsteroidsThatCollide(boundable);
		boolean removed = false;
		if (asteroidsThatCollide.size() > 0) {
			removed = true;
			asteroids.removeAll(asteroidsThatCollide);
		}
		return removed;
	}

	public void removeAsteroidsThatCollideWithOtherAsteroids() {
		List<Asteroid> asteroidsThatCollide = new ArrayList<Asteroid>();
		for (Asteroid asteroid : asteroids) {
			asteroidsThatCollide = findAsteroidsThatCollide(asteroid);
		}
		asteroids.removeAll(asteroidsThatCollide);
	}

	public int size() {
		return asteroids.size();
	}
}